//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	NamedEventHandlerInfoArray.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;

namespace Smart.Common
{
	public class NamedEventHandlerInfoArray : List<NamedEventHandlerInfo>
	{
		public bool NeedResort;

		public void SortByPriority()
		{
			Sort(
				(fst, snd) =>
					{
						var res = fst.Priority - snd.Priority;

						return res == 0 ? fst.AddIdx - snd.AddIdx : res;
					});

			NeedResort = false;
		}

		public void Register(Delegate handler, int priority)
		{
			NeedResort = true;

			Add(new NamedEventHandlerInfo(handler, priority, Count));
		}

		public void Unregister(Delegate handler)
		{
			var idx = FindIndex(info => info.Handler == handler);

			if (idx >= 0)
				RemoveAt(idx);
		}

		public bool FireEvent<TArg1>(string eventName, TArg1 arg1)
		{
			var res = true;

			if (NeedResort) SortByPriority();

			for (var i = 0; i < Count; i++)
			{
				var info = this[i];

				if (!info.FireEvent(eventName, arg1))
				{
					res = false;

					break;
				}
			}

			return res;
		}

		public bool FireEvent<TArg1, TArg2>(string eventName, TArg1 arg1, TArg2 arg2)
		{
			var res = true;

			if (NeedResort) SortByPriority();

			for (var i = 0; i < Count; i++)
			{
				var info = this[i];

				if (!info.FireEvent(eventName, arg1, arg2))
				{
					res = false;

					break;
				}
			}

			return res;
		}

		public bool FireEvent<TArg1, TArg2, TArg3>(string eventName, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			var res = true;

			if (NeedResort) SortByPriority();

			for (var i = 0; i < Count; i++)
			{
				var info = this[i];

				if (!info.FireEvent(eventName, arg1, arg2, arg3))
				{
					res = false;

					break;
				}
			}

			return res;
		}

		public bool FireEvent<TArg1, TArg2, TArg3, TArg4>(string eventName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			var res = true;

			if (NeedResort) SortByPriority();

			for (var i = 0; i < Count; i++)
			{
				var info = this[i];

				if (!info.FireEvent(eventName, arg1, arg2, arg3, arg4))
				{
					res = false;

					break;
				}
			}

			return res;
		}
	}
}